﻿#include "AF_Scene.h"
#include "AF_PublicFace.h"

namespace AF
{
	Scene::Scene(/*Window* pWindow*/) :
		m_isFullWindow(false),
		m_pBackScene(NULL),
		m_nReturn(AF_ID_OK),
		m_isExit(false),
		m_isStart(false),
		m_pLayout(NULL),
		m_pWindow(NULL),
		m_pCanvas(NULL),
		m_isUpdateCanvas(false),
		m_pPlatform(NULL)
	{
// 		SetWindow(pWindow);
		SetVisible(false);
	}

	Scene::~Scene()
	{
		if(m_pCanvas != NULL)
		{
			m_pCanvas->CleanGarphicses();
			AF_pTHEPLATFORM->DeleteCanvas(m_pCanvas);
			m_pCanvas = NULL;
		}

// 		if(m_pCanvas != NULL && m_pPlatform != NULL)
// 		{
// 			m_pPlatform->DeleteCanvas(m_pCanvas);
// 			m_pPlatform = NULL;
// 			m_pCanvas = NULL;
// 		}
// 
// 		m_pBackScene = NULL;
	}

	void Scene::SetLayout(Layout* pLayout)
	{
		if(m_pLayout == NULL)
			m_pLayout = pLayout;
	}

	Layout* Scene::GetLayout()
	{
		return m_pLayout;
	}

	bool Scene::SetWindow(Window* pWindow)
	{
		AF_CHECK_R(pWindow != NULL, false);

		if(m_isStart)
			return false;

		if(m_pWindow != pWindow && m_pCanvas != NULL)
		{
			m_pCanvas->CleanGarphicses();
			AF_pTHEPLATFORM->DeleteCanvas(m_pCanvas);
			m_pCanvas = NULL;
		}

		m_pWindow = pWindow;

		if(m_pCanvas == NULL)
		{
			m_pPlatform = AF_pTHEPLATFORM;
 			m_pCanvas = m_pPlatform->CreateCanvas(m_pWindow->GetHandle());
			m_isUpdateCanvas = true;
		}

		return true;
	}

	int Scene::Start(Scene* pBackScene)
	{
		AF_CHECK_R(m_pWindow != NULL, AF_ID_ERROR);
// 		AF_CHECK_R(m_pWindow->GetTopScene() != this, AF_ID_ERROR);
		AF_CHECK_R(m_pCanvas != NULL, AF_ID_ERROR);

		if(!OnStart())
			return AF_ID_CANCEL;

		if(!m_pCanvas->Enabled())
			return AF_ID_CANCEL;
		ResetCanvas();

		m_isStart = true;
		m_isExit = false;
		SetVisible(true);

		m_pBackScene = pBackScene;

		return AF_ID_OK;
	}

	bool Scene::Exit(bool isCommand)
	{
		bool isExit = true;

		// 询问底层场景是否可以退出
		if(m_pBackScene != NULL)
		{
			isExit = m_pBackScene->Exit(isCommand);
		}

		if(isCommand)
			return m_isExit = true;

		// 询问本场景
		if(isExit)
		{
			isExit = OnExit(isCommand);
		}

		return m_isExit = isExit;
	}

	int Scene::End()
	{
 		SetVisible(false);
		m_isStart = false;

 		m_pCanvas->Disabled();
 
 		OnEnd();

		m_pBackScene = NULL;

		return OnReturn();
	}

	bool Scene::IsStart()
	{
		return m_isStart;
	}

	bool Scene::IsExit()
	{
		return m_isExit;
	}

	void Scene::Update()
	{
		// 场景更新
		OnUpdate();		

		// 窗口更新
		if(m_pWindow->GetTopScene() == this)
		{
			m_pWindow->UpdateWindow();
		}

		// 应用程序更新
		AF_pTHEAPP->UpdateApp();
	}

	int Scene::GetReturn()
	{
		return m_nReturn;
	}

	void Scene::UpdateCanvas()
	{
		m_isUpdateCanvas = true;
	}

	void Scene::ResetCanvas()
	{
		AF_CHECK(m_pCanvas);

		if(!m_isUpdateCanvas)
			return;

		RefreshSize();

		m_pCanvas->CleanGarphicses();

		// 添加场景自己
		m_pCanvas->AddGraphics(this);

		// 添加布局内容
		if(m_pLayout != NULL)
		{
			FOREACH_P(Graphics, _pG, m_pLayout)
			{
				if(_pG->GetGType() == AF_GRAPHICS_FACE)
					((Face*)_pG)->RefreshSize();
				AddToCanvas(_pG);
			}
		}

		// 添加其他子项
		FOREACH_P(Graphics, _pG, this)
		{
			if(_pG->GetGType() == AF_GRAPHICS_FACE)
				((Face*)_pG)->RefreshSize();
			AddToCanvas(_pG);
		}

		// 将公共界面添加至队列
		PublicFace::AddToScene(this);

		m_isUpdateCanvas = false;
	}

	void Scene::AddToCanvas(Graphics* pGraphics)
	{
		// 添加自己
		m_pCanvas->AddGraphics(pGraphics);

		// 添加子项
		FOREACH_P(Graphics, _pG, pGraphics)
		{
			AddToCanvas(_pG);
		}
	}

	void Scene::FullWindow(bool isFullWindow)
	{
		m_isFullWindow = isFullWindow;
	}

	bool Scene::IsFullWindow()
	{
		return m_isFullWindow;
	}

	Scene* Scene::GetBackScene()
	{
		return m_pBackScene;
	}
	
	Window* Scene::GetWindow()
	{
		return m_pWindow;
	}

	Size* Scene::GetWindowSize()
	{
		AF_CHECK_R(m_pWindow != NULL, NULL);
		return &m_pWindow->GetSize();
	}

	Canvas* Scene::GetCanvas()
	{
		return m_pCanvas;
	}

	void Scene::Return(int nReturn)
	{
		m_nReturn = nReturn;
		m_isExit = true;
	}

	void Scene::ReturnOK()
	{
		m_nReturn = AF_ID_OK;
		m_isExit = true;
	}

	void Scene::ReturnCancel()
	{
		m_nReturn = AF_ID_CANCEL;
		m_isExit = true;
	}

	void Scene::ReturnYes()
	{
		m_nReturn = AF_ID_YES;
		m_isExit = true;
	}

	void Scene::ReturnNo()
	{
		m_nReturn = AF_ID_NO;
		m_isExit = true;
	}

	void Scene::ReturnError(int nErrorCode)
	{
		if(nErrorCode >= AF_ID_ERROR)
			m_nReturn = nErrorCode;
		else
			m_nReturn = AF_ID_ERROR;
		m_isExit = true;
	}
}
